﻿/*
 * Rappelz: Endless Odyssey - The first free open source Rappelz server emulator
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Rappelz.GameServer.Database;
using Rappelz.GameServer.Network;
using Rappelz.GameServer.Network.GameClient;
using Rappelz.GameServer.Network.AuthClient;
using System.Threading;
using Rappelz.GameServer.Scripting;

namespace Rappelz.GameServer
{
    public class RappelzData
    {
//         UserDefinedType: ArcadiaData
//         Function       :   public void ArcadiaData::~ArcadiaData()
        public ArRegionContainer pRgnMgr;
        public ExclusiveLogicLock rgnLock;

/*
        Data           :   this+0x8, Member, Type: class ExclusiveLogicLock<ArBoxCollision,XCriticalSection>, rgnLock
        UserDefinedType:     ExclusiveLogicLock<ArBoxCollision,XCriticalSection>
*/

        public RappelzScheduler scheduler; //         Data           :   this+0x920, Member, Type: class ArScheduler, 
//         UserDefinedType:     ArScheduler
// 
//         Function       :   public void ArcadiaData(const struct ArcadiaData &)
//         Function       :   public void ArcadiaData::ArcadiaData()
//         Function       :   public struct ArcadiaData & operator=(const struct ArcadiaData &)
//         Function       :   public void * __vecDelDtor(unsigned int)

    }

    public class RappelzServer
    {
        public static GameDBManager arcman;
        /// <summary>
        /// The instance!
        /// </summary>
        protected static RappelzServer m_instance;

        /// <summary>
        /// The TCP Manager
        /// </summary>
        protected TCPManager m_netManager;

        /// <summary>
        /// Returns the instance
        /// </summary>
        public static RappelzServer Instance
        {
            get { return m_instance; }
        }

        /// <summary>
        /// Constructs an AuroraServer object
        /// </summary>
        protected RappelzServer()
        {
            Config.Load(Globals.AppPath + "\\gameserver.xml");
            Globals.Log = new XLog(Globals.AppPath + "\\Logs\\GameServer");
            Globals.Log.Level = Config.bDebug ? XLog.Levels.Debug : XLog.Levels.Info;
            Globals.Log.Info("-");
            Globals.Log.Info("- Rappelz: Emulator - Game Emulator");
            Globals.Log.Info("-");

            // Create the thread object, passing in the Alpha.Beta method
            // via a ThreadStart delegate. This does not start the thread.
            Thread oThread = new Thread(new ThreadStart(this.Load));

            // Start the thread
            oThread.Start();


        }

        /// <summary>
        /// Creates our AuroraServer instance
        /// </summary>
        public static void CreateInstance()
        {
            if (m_instance == null)
                m_instance = new RappelzServer();
        }

        public void Load()
        {
            MemoryPool.Init();
            GameContent.g_SeamlessWorldInfo.Initialize("TerrainSeamlessWorld.cfg", false);
            this.m_nMapWidth = GameContent.g_nMapWidth;
            this.m_nMapHeight = GameContent.g_nMapHeight;

            ChannelManager.Init();
            m_Data.pRgnMgr = new ArRegionContainer(this.m_nMapWidth, this.m_nMapHeight);
            m_Data.scheduler = new RappelzScheduler(GameRule.nSchedulerThreads);
            m_Data.rgnLock = new ExclusiveLogicLock();

            InitLua();

            //            	XSetThreadName(-1, "GameLoader");
            //	CoInitialize(0);
            //	InitGameHeap();
            //	InitDBHeap();
            //	XSEH::SetUserFunc(CaptainHerlockExceptionFilter);

            Item.InitItemSystem();//(v1);
            Creature.InitCreatureSystem();

            //	InitArcadia();
            //	LoadResource();

            //ResourceManager.Init();


            FieldPropManager.Init();
 	        EventItemManager.Init();
            ItemCollector.Init();

            LoadDb();
// 	        GameContent.LoadScript();



            LuaVM.Instance.RunString("on_server_init()");
//	        worker.WaitForPendingWork();

            GameContent.AddNPCToWorld();
	        GameContent.AddRespawnObjectToWorld();
//	        worker.EndThread();


            RoamingManager.Instance.Init();


            m_netManager = new TCPManager(Config.srvGameClients.ConnLimit + 5, 2048 * 3);
            GameClientNetwork.CreateInstance(m_netManager);
            AuthClientNetwork.CreateInstance(m_netManager);
            AuthClientNetwork.Instance.Connect();

            RunProcessPump();
        }

        private void LoadDb()
        {
            GameDBManager.CreateInstance(Config.dbTelecaster);
            GameDBManager.Instance.Push(new DB_OnStartUp());
            GameDBManager.Instance.WaitUntilEmpty();

            arcman = new GameDBManager(Config.dbArcadia);
            arcman.Push(new DBLoader_String(arcman));
            arcman.WaitUntilEmpty();
            GameDBManager.Instance.WaitUntilEmpty();

            arcman.Push(new DBLoader_Monster(arcman));
            arcman.Push(new DBLoader_Item(arcman));
            arcman.Push(new DBLoader_ItemEffect(arcman));
            arcman.Push(new DBLoader_AuctionCategory(arcman));
            arcman.WaitUntilEmpty();
            GameDBManager.Instance.WaitUntilEmpty();

            arcman.Push(new DBLoader_Skill(arcman));
//             arcman.Push(new DBLoader_Bitmap(arcman));
            DBLoader_Map map_loader = new DBLoader_Map(arcman);
            arcman.Push(map_loader);
//            arcman.Push(new DBLoader_AutoAuction(arcman));
            arcman.WaitUntilEmpty();
            GameDBManager.Instance.WaitUntilEmpty();

            arcman.Push(new DBLoader_Etc(arcman));
            arcman.Push(new DBLoader_Quest(arcman));
            arcman.Push(new DBLoader_Location(arcman));
//            arcman.Push(new DBLoader_AutoAuctionRegistrationInfo(arcman));
            arcman.WaitUntilEmpty();
            GameDBManager.Instance.WaitUntilEmpty();

            arcman.Push(new DBLoader_Guild(arcman));
            arcman.Push(new DBLoader_Channel(arcman));
            arcman.Push(new DBLoader_Dungeon(arcman));
            arcman.Push(new DBLoader_Mix(arcman));
            arcman.WaitUntilEmpty();
            GameDBManager.Instance.WaitUntilEmpty();

            arcman.Push(new DBLoader_FieldProp(arcman));
            arcman.Push(new DBLoader_Roaming(arcman));
//             arcman.Push(new DBLoader_FieldPropSwitching(arcman));
//             arcman.Push(new DBLoader_Auction(arcman));
            arcman.WaitUntilEmpty();
            GameDBManager.Instance.WaitUntilEmpty();

//             arcman.Push(new DBLoader_Party(arcman));
            arcman.Push(new DBLoader_FieldPropData(arcman));
            arcman.Push(new DBLoader_AllowedCommandsList(arcman));
//             arcman.Push(new DBLoader_ScheduledCommand(arcman));
            arcman.WaitUntilEmpty();
            GameDBManager.Instance.WaitUntilEmpty();

            arcman.Push(new DBLoader_NPC(arcman));
            arcman.Push(new DBLoader_Pet(arcman));
//             arcman.Push(new DBLoader_Huntaholic(arcman));
//             arcman.Push(new DBLoader_Ranking(arcman));
            arcman.WaitUntilEmpty();
            GameDBManager.Instance.WaitUntilEmpty();

            arcman.WaitUntilEmpty();
            GameDBManager.Instance.WaitUntilEmpty();
 
/*
*/

//	ENV().Set("game.loading", "complete");
//
//	DungeonManager::Instance().Init();
//	AuctionManager::Instance().Init();
//	RoamingManage::Instance().Init();
//	HuntaholicManager::Instance().Init();
//	CompeteManager::Instance().Init();
//	RankingManager::Instance().Init();

//	if(ENV().IsExist("engine.perf_log_name"))
//	{
//		XPerformanceGuard::s_bUseFlag = 1;
//		XPerformanceGuard::s_strLogFileName = ENV().GetString("engine.perf_log_name", "PerfGuardLog.txt");
//	}
//	InitMessageLogger();

            map_loader.InitMapInfo();
        }

        public void InitLua()
        {
            Globals.Log.Info("Initializing Lua.");

	        if(LuaVM.Init())
	        {
		        Globals.Log.Info("LUA initialize...   ok");
	        }
	        else
	        {
		        Globals.Log.Info("LUA initialize...   Failed");
	        }

// 	LuaVM::Inst()->RegisterFunction("is_erasable_item", SCRIPT_IsErasableItem);
// 	LuaVM::Inst()->RegisterFunction("drop_item", SCRIPT_DropItem);
// 	LuaVM::Inst()->RegisterFunction("drop_gold", SCRIPT_DropGold);
// 	LuaVM::Inst()->RegisterFunction("insert_gold", SCRIPT_InsertGold);
// 	LuaVM::Inst()->RegisterFunction("has_item", SCRIPT_HasItem);
// 	LuaVM::Inst()->RegisterFunction("get_item_soulstone_endurance", SCRIPT_GetItemSoulStoneEndurance);
// 	LuaVM::Inst()->RegisterFunction("get_max_item_soulstone_endurance", SCRIPT_GetMaxItemSoulStoneEndurance);
// 	LuaVM::Inst()->RegisterFunction("event_drop", SCRIPT_EventDrop);
// 	LuaVM::Inst()->RegisterFunction("refresh_event_drop", SCRIPT_RefreshEventDropInfo);
// 	LuaVM::Inst()->RegisterFunction("start_event_drop", SCRIPT_StartEventDrop);
// 	LuaVM::Inst()->RegisterFunction("stop_event_drop", SCRIPT_StopEventDrop);
// 	LuaVM::Inst()->RegisterFunction("event_supply", SCRIPT_EventSupply);
// 	LuaVM::Inst()->RegisterFunction("refresh_event_supply", SCRIPT_RefreshEventSupplyInfo);
// 	LuaVM::Inst()->RegisterFunction("start_event_supply", SCRIPT_StartEventSupply);
// 	LuaVM::Inst()->RegisterFunction("stop_event_supply", SCRIPT_StopEventSupply);
// 	LuaVM::Inst()->RegisterFunction("supply_event_item", SCRIPT_SupplyEventItem);
// 	LuaVM::Inst()->RegisterFunction("get_value", SCRIPT_GetValue);
// 	LuaVM::Inst()->RegisterFunction("add_value", SCRIPT_AddValue);
// 	LuaVM::Inst()->RegisterFunction("set_value", SCRIPT_SetValue);
// 	LuaVM::Inst()->RegisterFunction("echo_value", SCRIPT_EchoValue);
// 	LuaVM::Inst()->RegisterFunction("gv", SCRIPT_GetValue);
// 	LuaVM::Inst()->RegisterFunction("av", SCRIPT_AddValue);
// 	LuaVM::Inst()->RegisterFunction("sv", SCRIPT_SetValue);
// 	LuaVM::Inst()->RegisterFunction("ev", SCRIPT_EchoValue);
// 	LuaVM::Inst()->RegisterFunction("get_all_value", SCRIPT_GetAllValue);
// 	LuaVM::Inst()->RegisterFunction("change_creature_name", SCRIPT_ChangeCreatureName);
// 	LuaVM::Inst()->RegisterFunction("scv", SCRIPT_SetCreatureValue);
// 	LuaVM::Inst()->RegisterFunction("smcv", SCRIPT_SetMainCreatureValue);
// 	LuaVM::Inst()->RegisterFunction("gcv", SCRIPT_GetCreatureValue);
// 	LuaVM::Inst()->RegisterFunction("gmcv", SCRIPT_GetMainCreatureValue);
// 	LuaVM::Inst()->RegisterFunction("emcv", SCRIPT_EchoMainCreatureValue);
// 	LuaVM::Inst()->RegisterFunction("get_flag", SCRIPT_GetPlayerFlag);
// 	LuaVM::Inst()->RegisterFunction("set_flag", SCRIPT_SetPlayerFlag);
// 	LuaVM::Inst()->RegisterFunction("del_flag", SCRIPT_RemovePlayerFlag);
// 	LuaVM::Inst()->RegisterFunction("set_pk_mode", SCRIPT_SetPKMode);
// 	LuaVM::Inst()->RegisterFunction("is_alliance_leader", SCRIPT_IsAllianceLeader);
// 	LuaVM::Inst()->RegisterFunction("increase_max_alliance_member_count", SCRIPT_IncreaseMaxAllianceMemberCount);
// 	LuaVM::Inst()->RegisterFunction("get_max_alliance_member_count", SCRIPT_GetMaxAllianceMemberCount);
// 	LuaVM::Inst()->RegisterFunction("kick", SCRIPT_Kick);
// 	LuaVM::Inst()->RegisterFunction("force_unregister_account", SCRIPT_ForceUnregisterAccount);
// 	LuaVM::Inst()->RegisterFunction("env", SCRIPT_GetEnv);
// 	LuaVM::Inst()->RegisterFunction("add_npc_to_world", SCRIPT_AddNPC);
// 	LuaVM::Inst()->RegisterFunction("respawn", SCRIPT_AddRespawnInfo);
// 	LuaVM::Inst()->RegisterFunction("respawn_guardian", SCRIPT_AddDungeonGuardianRespawnInfo);
// 	LuaVM::Inst()->RegisterFunction("respawn_environmental_guardian", SCRIPT_AddDungeonEnvironmentalGuardianRespawnInfo);
// 	LuaVM::Inst()->RegisterFunction("respawn_rare_mob", SCRIPT_AddRareMobRespawnInfo);
// 	LuaVM::Inst()->RegisterFunction("respawn_roaming_mob", SCRIPT_AddRoamingMobRespawnInfo);
// 	LuaVM::Inst()->RegisterFunction("raid_respawn", SCRIPT_AddRaidRespawnInfo);
// 	LuaVM::Inst()->RegisterFunction("raid_respawn_rare_mob", SCRIPT_AddRaidRareMobRespawnInfo);
// 	LuaVM::Inst()->RegisterFunction("kill", SCRIPT_Kill);
// 	LuaVM::Inst()->RegisterFunction("kill_target", SCRIPT_KillTarget);

// 	LuaVM::Inst()->RegisterFunction("whisper", SCRIPT_Whisper);

// 	LuaVM::Inst()->RegisterFunction("recall_player", SCRIPT_RecallPlayer);
// 	LuaVM::Inst()->RegisterFunction("is_in_siege_dungeon", SCRIPT_IsInSiegeDungeon);
// 	LuaVM::Inst()->RegisterFunction("respawn_guardian_object", SCRIPT_RespawnGuardian);
// 	LuaVM::Inst()->RegisterFunction("show_dungeon_stone", SCRIPT_ShowDungeonStone);
// 	LuaVM::Inst()->RegisterFunction("change_tactical_position_owner", SCRIPT_ChangeTacticalPositionOwner);
// 	LuaVM::Inst()->RegisterFunction("request_dungeon_raid", SCRIPT_RequestDungeonRaid);
// 	LuaVM::Inst()->RegisterFunction("begin_dungeon_raid", SCRIPT_BeginDungeonRaid);
// 	LuaVM::Inst()->RegisterFunction("drop_dungeon_owner_ship", SCRIPT_DropDungeonOwnership);
// 	LuaVM::Inst()->RegisterFunction("change_dungeon_owner", SCRIPT_ChangeDungeonOwner);
// 	LuaVM::Inst()->RegisterFunction("clear_dungeon_core_guardian", SCRIPT_ClearDungeonCoreGuardian);

// 	LuaVM::Inst()->RegisterFunction("stat", SCRIPT_Stat);
// 	LuaVM::Inst()->RegisterFunction("setspeed", SCRIPT_SetSpeed);
// 	LuaVM::Inst()->RegisterFunction("saveall", SCRIPT_SaveAllPlayer);
// 	LuaVM::Inst()->RegisterFunction("shutdown", SCRIPT_Shutdown);
// 	LuaVM::Inst()->RegisterFunction("delete_block_account", SCRIPT_DeleteFromBlockAccount);

// 	LuaVM::Inst()->RegisterFunction("set_next_attackable_time", SCRIPT_SetNextAttackableTime);
// 	LuaVM::Inst()->RegisterFunction("force_monster_proc_dead", SCRIPT_ForceMonsterProcDead);

// 	LuaVM::Inst()->RegisterFunction("gametime", SCRIPT_GetGameTime);
// 	LuaVM::Inst()->RegisterFunction("refresh", SCRIPT_Reload);
// 	LuaVM::Inst()->RegisterFunction("learn_skill", SCRIPT_LearnSkill);
// 	LuaVM::Inst()->RegisterFunction("learn_all_skill", SCRIPT_LearnAllSkill);
// 	LuaVM::Inst()->RegisterFunction("learn_creature_all_skill", SCRIPT_LearnCreatureAllSkill);
// 	LuaVM::Inst()->RegisterFunction("get_base_skill_level", SCRIPT_GetBaseSkillLevel);
// 	LuaVM::Inst()->RegisterFunction("show_creature_dialog", SCRIPT_ShowCreatureDialog);
// 	LuaVM::Inst()->RegisterFunction("sconv", SCRIPT_Conv);
// 	LuaVM::Inst()->RegisterFunction("message", SCRIPT_Message);
// 	LuaVM::Inst()->RegisterFunction("is_changeable_job", SCRIPT_IsChangeableJob);
// 	LuaVM::Inst()->RegisterFunction("add_state", SCRIPT_AddState);
// 	LuaVM::Inst()->RegisterFunction("remove_state", SCRIPT_RemoveState);
// 	LuaVM::Inst()->RegisterFunction("add_cstate", SCRIPT_AddCreatureState);
// 	LuaVM::Inst()->RegisterFunction("remove_cstate", SCRIPT_RemoveCreatureState);
// 	LuaVM::Inst()->RegisterFunction("set_env", SCRIPT_SetEnv);
// 	LuaVM::Inst()->RegisterFunction("get_env", SCRIPT_GetEnv);
// 	LuaVM::Inst()->RegisterFunction("set_global_variable", SCRIPT_SetGlobalVariable);
// 	LuaVM::Inst()->RegisterFunction("get_global_variable", SCRIPT_GetGlobalVariable);
// 	LuaVM::Inst()->RegisterFunction("del_global_variable", SCRIPT_DeleteGlobalVariable);
// 	LuaVM::Inst()->RegisterFunction("get_string", SCRIPT_GetString);
// 	LuaVM::Inst()->RegisterFunction("get_user_count_near", SCRIPT_GetUserCountNear);

// 	LuaVM::Inst()->RegisterFunction("destroy_guild", SCRIPT_DestroyGuild);
// 	LuaVM::Inst()->RegisterFunction("show_alliance_create", SCRIPT_ShowCreateAlliance);
// 	LuaVM::Inst()->RegisterFunction("force_change_guild_name", SCRIPT_ForceChangeGuildName);
// 	LuaVM::Inst()->RegisterFunction("force_promote_guild_leader", SCRIPT_ForcePromoteGuildLeader);
// 	LuaVM::Inst()->RegisterFunction("create_alliance", SCRIPT_CreateAlliance);
// 	LuaVM::Inst()->RegisterFunction("destroy_alliance", SCRIPT_DestroyAlliance);
// 	LuaVM::Inst()->RegisterFunction("check_valid_alliance_name", SCRIPT_CheckValidAllianceName);
// 	LuaVM::Inst()->RegisterFunction("get_npc_handle", SCRIPT_GetNPCHandle);
// 	LuaVM::Inst()->RegisterFunction("call_lc_In", SCRIPT_SetCurrentLocationId);
// 	LuaVM::Inst()->RegisterFunction("creature_learn_skill", SCRIPT_CreatureLearnSkill);
// 	LuaVM::Inst()->RegisterFunction("get_proper_channel_num", SCRIPT_GetProperChannelNo);
// 	LuaVM::Inst()->RegisterFunction("get_min_channel_num", SCRIPT_GetMinChannelNo);
// 	LuaVM::Inst()->RegisterFunction("get_max_channel_num", SCRIPT_GetMaxChannelNo);
// 	LuaVM::Inst()->RegisterFunction("get_user_count_in_channel", SCRIPT_GetUserCountInChannel);
// 	LuaVM::Inst()->RegisterFunction("get_layer_of_channel", SCRIPT_GetLayerOfChannel);
// 	LuaVM::Inst()->RegisterFunction("get_summon_name_id", SCRIPT_GetSummonNameId);
// 	LuaVM::Inst()->RegisterFunction("equip_summon_card", SCRIPT_EquipSummonCard);
// 	LuaVM::Inst()->RegisterFunction("show_channel_set", SCRIPT_ShowChannelSet);
// 	LuaVM::Inst()->RegisterFunction("update_guild_info", SCRIPT_UpdateGuildInfo);
// 	LuaVM::Inst()->RegisterFunction("is_guild_leader", SCRIPT_IsGuildLeader);
// 	LuaVM::Inst()->RegisterFunction("set_guild_block_time", SCRIPT_SetGuildBlockTime);
// 	LuaVM::Inst()->RegisterFunction("get_guild_block_time", SCRIPT_GetGuildBlockTime);
// 	LuaVM::Inst()->RegisterFunction("get_own_guild_name", SCRIPT_GetOwnGuildName);
// 	LuaVM::Inst()->RegisterFunction("get_tax_rate", SCRIPT_GetTaxRate);
// 	LuaVM::Inst()->RegisterFunction("set_tax_rate", SCRIPT_SetTaxRate);
// 	LuaVM::Inst()->RegisterFunction("get_tax_amount", SCRIPT_GetTaxAmount);
// 	LuaVM::Inst()->RegisterFunction("get_tax_chaos_amount", SCRIPT_GetTaxChaosAmount);
// 	LuaVM::Inst()->RegisterFunction("draw_tax", SCRIPT_DrawTax);
// 	LuaVM::Inst()->RegisterFunction("draw_tax_chaos", SCRIPT_DrawTaxChaos);
// 	LuaVM::Inst()->RegisterFunction("add_way_point", SCRIPT_AddWayPoint);
            
// 	LuaVM::Inst()->RegisterFunction("set_way_point_speed", SCRIPT_SetWayPointSpeed);
// 	LuaVM::Inst()->RegisterFunction("recall_feather", SCRIPT_RecallFeather);
// 	LuaVM::Inst()->RegisterFunction("warp_to_revive_position", SCRIPT_WarpToRevivePosition);
// 	LuaVM::Inst()->RegisterFunction("get_server_category", SCRIPT_GetServerCategory);
// 	LuaVM::Inst()->RegisterFunction("find_npc", SCRIPT_FindNPC);
// 	LuaVM::Inst()->RegisterFunction("set_auto_user", SCRIPT_SetAutoUser);
// 	LuaVM::Inst()->RegisterFunction("set_auto_account", SCRIPT_SetAutoAccount);
// 	LuaVM::Inst()->RegisterFunction("clear_auto_account", SCRIPT_ClearAutoAccount);
// 	LuaVM::Inst()->RegisterFunction("open_url", SCRIPT_OpenUrl);
// 	LuaVM::Inst()->RegisterFunction("open_popup", SCRIPT_OpenPopup);
// 	LuaVM::Inst()->RegisterFunction("open_popup_and_set_size", SCRIPT_OpenPopupAndSetSize);
// 	LuaVM::Inst()->RegisterFunction("get_local_info", SCRIPT_GetLocalInfo);
// 	LuaVM::Inst()->RegisterFunction("show_donation_prop", SCRIPT_ShowDonationMenu);
// 	LuaVM::Inst()->RegisterFunction("set_pcbang_user", SCRIPT_SetPCBangUser);
// 	LuaVM::Inst()->RegisterFunction("set_continuous_play_time", SCRIPT_SetContinuousPlayTime);
// 	LuaVM::Inst()->RegisterFunction("get_creature_name_id", SCRIPT_GetCreatureNameID);
// 	LuaVM::Inst()->RegisterFunction("creature_name_change_box", SCRIPT_ShowCreatureNameChangeBox);
// 	LuaVM::Inst()->RegisterFunction("reset_summon_skill", SCRIPT_ResetSummonSkill);
// 	LuaVM::Inst()->RegisterFunction("show_auction_window", SCRIPT_ShowAuctionWindow);
// 	LuaVM::Inst()->RegisterFunction("cancel_auction_by_seller", SCRIPT_CancelAuctionBySeller);
// 	LuaVM::Inst()->RegisterFunction("warp_to_huntaholic_lobby", SCRIPT_WarpToHuntaholicLobby);
// 	LuaVM::Inst()->RegisterFunction("exit_huntaholic_lobby", SCRIPT_ExitHuntaholicLobby);
// 	LuaVM::Inst()->RegisterFunction("show_huntaholic_lobby_window", SCRIPT_ShowHuntaholicLobbyWindow);
// 	LuaVM::Inst()->RegisterFunction("set_huntaholic_point", SCRIPT_SetHuntaholicPoint);
// 	LuaVM::Inst()->RegisterFunction("suicide", SCRIPT_Suicide);
// 	LuaVM::Inst()->RegisterFunction("set_scheduled_command_manager_priority", SCRIPT_SetScheduledCommandManagerPriority);
// 	StructSummon::BindProperty();
// 	StructPlayer::BindProperty();

	//LuaVM::Inst()->BindLogOutputFunction(ScriptLog);

        }

        /// <summary>
        /// Closes our server
        /// </summary>
        public void Close()
        {
            AuthClientNetwork.Instance.Close();
            RappelzServer.m_Data.scheduler.DeInit();
        }


        public void AddObject(BaseObject obj)
        {
            ArRegion region = m_Data.pRgnMgr.GetRegion(obj);
            if (region == null) return;


            float frs = (float)GameContent.g_nRegionSize;

            ArcadiaServerAddObjectArRegionFunctor rf = new ArcadiaServerAddObjectArRegionFunctor();
            rf.obj = obj;
            m_Data.pRgnMgr.DoEachVisibleRegion((uint)(obj.mv.x / frs), (uint)(obj.mv.y / frs), obj.m_layer, rf);

            if (obj.m_nArObjectType != 0)
            {
                if (obj.m_nArObjectType == 1 )
                {
                    Interlocked.Increment(ref this.m_nNPCCount);
                }
                else
                {
                    if (obj.m_nArObjectType != 2 )
                        return;
                    Interlocked.Increment(ref this.m_nUserCount);
                }
            }
            else
            {
                Interlocked.Increment(ref this.m_nItemCount);
            }
            region.AddObject(obj);
        }

        public void DeleteObject(BaseObject obj)
        {
            if (obj.priority != SchedulerObject.Priority.Idle)
                this.SetObjectPriority(obj, SchedulerObject.Priority.Idle);
            m_Data.scheduler.DeleteObject(obj);
        }

        public void AddSummonToWorld(Summon summon)
        {
            summon.quadTreeItem.Set(summon);
            summon.quadTreeItem.AddMe();

            summon.m_StatusFlag |= Creature.StatusFlags.FirstEnter;

            RappelzServer.Instance.AddObject(summon);
            summon.m_bIsSummoned = true;
            summon.m_StatusFlag &= ~Creature.StatusFlags.FirstEnter;
            this.SetObjectPriority(summon, SchedulerObject.Priority.Normal);
        }

        public void AddPetToWorld(Pet pet)
        {
            pet.quadTreeItem.Set(pet);
            pet.quadTreeItem.AddMe();

            pet.m_StatusFlag |= Creature.StatusFlags.FirstEnter;

            RappelzServer.Instance.AddObject(pet);
            pet.m_bIsSummoned = true;
            pet.m_StatusFlag &= ~Creature.StatusFlags.FirstEnter;
            this.SetObjectPriority(pet, SchedulerObject.Priority.Normal);
        }

        public bool SetMove(BaseObject obj, ArPosition curPos, ArPosition newPos, sbyte speed, bool bAbsoluteMove, uint t, bool bBroadcastMove)
        {
            ArPosition oldPos = new ArPosition();
            ArPosition curPos2 = new ArPosition();

            if (bAbsoluteMove ||  RappelzServer.m_Intf.onSetMove(obj, curPos, newPos))
            {
                if (obj.mv.bIsMoving && obj.bIsInWorld)
                {
                    oldPos.Copy(obj.mv);
                    obj.SetCurrentXY(curPos.x, curPos.y);
                    curPos2.Copy(obj.mv);
                    this.onMoveObject(obj, oldPos, curPos2);
                    this.enterProc(obj,(uint)(oldPos.x / (float)GameContent.g_nRegionSize),(uint)(oldPos.y / (float)GameContent.g_nRegionSize));
                    obj.SetMove(newPos, (byte)speed, t);
                }
                else
                {
                    obj.SetMove(newPos, (byte)speed, t);
                }
                if (bBroadcastMove)
                {
                    ArcadiaServerSetMoveArRegionFunctor fn = new ArcadiaServerSetMoveArRegionFunctor();
                    fn.obj = obj;
                    RappelzServer.m_Data.pRgnMgr.DoEachVisibleRegion((uint)(obj.mv.x / (float)GameContent.g_nRegionSize),
                        (uint)(obj.mv.y / (float)GameContent.g_nRegionSize),obj.m_layer, fn);
                    if (obj.m_nArObjectType != 2 )
                    {
                        if (obj.m_nArObjectType == 1)
                        {
                            if (fn.nCnt != 0 )
                            {
                                obj.bIsNearClient = true;
                                if (obj.priority == SchedulerObject.Priority.Idle || obj.pending_priority == SchedulerObject.Priority.Lowest)
                                    this.SetObjectPriority(obj, SchedulerObject.Priority.Normal);
                            }
                            else
                            {
                                obj.bIsNearClient = false;
                            }
                        }
                    }
                }
                return true;
            }
            return false;
        }

        public bool SetMultipleMove(GameObject pObject, ArPosition curPos, List<ArPosition> newPos, sbyte speed, bool bAbsoluteMove, uint t, bool bBroadcastMove)
        {
            ArPosition oldPos = new ArPosition();
            ArPosition lastpos = newPos.Last();

            
            bool result = false;
            if ( bAbsoluteMove || m_Intf.onSetMove(pObject,curPos,lastpos))
            {
                oldPos.x = pObject.mv.x;
                oldPos.y = pObject.mv.y;
                oldPos.z = pObject.mv.z;
                oldPos.face = pObject.mv.face;
                pObject.SetCurrentXY(curPos.x, curPos.y);
                curPos.x = pObject.mv.x;
                curPos.y = pObject.mv.y;
                curPos.z = pObject.mv.z;
                curPos.face = pObject.mv.face;
                this.onMoveObject(pObject, oldPos, curPos);
                float fregionSize = (float)GameContent.g_nRegionSize;
                this.enterProc(pObject,(uint)(oldPos.x / fregionSize),(uint)(oldPos.y / fregionSize));
                pObject.SetMultipleMove(newPos, (byte)speed, t);
                if (bBroadcastMove)
                {
                    ArcadiaServerSetMultipleMoveArRegionFunctor rf = new ArcadiaServerSetMultipleMoveArRegionFunctor();
                    rf.obj = pObject;
                    RappelzServer.m_Data.pRgnMgr.DoEachVisibleRegion((uint)(pObject.mv.x / fregionSize), (uint)(pObject.mv.y / fregionSize), pObject.m_layer, rf);
                    byte ot = pObject.m_nArObjectType;
                    if (ot != 2 && ot == 1)
                    {
                        if (rf.nCnt != 0)
                        {
                            pObject.bIsNearClient = true;
                            if (pObject.priority == SchedulerObject.Priority.Null || pObject.priority == SchedulerObject.Priority.Idle)
                                this.SetObjectPriority(pObject, SchedulerObject.Priority.Normal);
                        }
                        else
                        {
                            pObject.bIsNearClient = false;
                        }
                    }
                }
                result = true;
            }
            return result;
        }

        // UserDefinedType: ArcadiaServer
        // VTable         :   , Type:  *
        // Function       :   public void ~ArcadiaServer()
        // Function       :   public bool ArcadiaServer::Init(struct ArcadiaIntf *, float, float, function  *)
        // Function       :   public bool ArcadiaServer::DeInit()
        
        public void SetObjectPriority(SchedulerObject obj, SchedulerObject.Priority priority)
        {
            if (obj.priority != priority || obj.pending_priority != SchedulerObject.Priority.Null)
            {
                if (obj.pending_priority != priority)
                {
                    if (RappelzServer.m_Data != null && RappelzServer.m_Data.scheduler != null)
                    {
                        RappelzServer.m_Data.scheduler.SetObjectPriority(obj, priority);
                    }
                }
            }
        }
        
        public void onRegionChange(BaseObject obj, uint update_time, bool bIsStopMessage)
        {
//            Globals.GetArTime();

            float frs = GameContent.g_nRegionSize;
            uint oldx = (uint)(obj.mv.x / frs);
            uint oldy = (uint)(obj.mv.y / frs);
            obj.bIsRegionChanging = true;
            this.step(obj, (uint)(update_time + obj.lastStepTime + (bIsStopMessage ? 0xA : 0)));

            if ((uint)(obj.mv.x / frs) != oldx || (uint)(obj.mv.y / frs) != oldy)
            {
                this.enterProc(obj, oldx, oldy);
                obj.prev_rx = (int)oldx;
                obj.prev_ry = (int)oldy;
            }
            obj.bIsRegionChanging = false;
        }
        
        public uint Broadcast(uint rx1, uint ry1, uint rx2, uint ry2, byte layer, PacketOut packet)
        {
            ArcadiaServerMessageSenderArObjectFunctor sender = new ArcadiaServerMessageSenderArObjectFunctor();
            ArcadiaServerBroadcastSenderArRegionFunctor fn = new ArcadiaServerBroadcastSenderArRegionFunctor();

            sender.msg = packet;
            sender.pIntf = RappelzServer.m_Intf;
            fn.pFo = sender;
            RappelzServer.m_Data.pRgnMgr.DoEachVisibleRegion(rx1, ry1, rx2, ry2, layer, fn);
            return 0;
        }
        
        public uint Broadcast(uint rx, uint ry, byte layer, PacketOut packet)
        {
            ArcadiaServerMessageSenderArObjectFunctor sender = new ArcadiaServerMessageSenderArObjectFunctor();
            ArcadiaServerBroadcastSenderArRegionFunctor fn = new ArcadiaServerBroadcastSenderArRegionFunctor();

            sender.msg = packet;
            sender.pIntf = RappelzServer.m_Intf;
            fn.pFo = sender;
            RappelzServer.m_Data.pRgnMgr.DoEachVisibleRegion(rx, ry, layer, fn);
            return 0;
        }

        // Function       :   public unsigned int ArcadiaServer::BroadcastToSpecificRegion(unsigned int, unsigned int, unsigned int, unsigned char, const void *)
        // Function       :   public void ArcadiaServer::AddObject(struct ArObject *)
        
        public void RemoveObject(BaseObject pObject)
        {
//Data           :   enregistered ecx, Object Ptr, Type: const struct ArcadiaServer::RemoveObject::__l7::_ArRegionFunctor::_SendLeaveMessage * const, this

            ArRegion region = RappelzServer.m_Data.pRgnMgr.GetRegion(pObject);
//             if ( g_bUseRegionDebug )
//             {
//                 pObjecta = pObject->mv.baseclass_0.y;
//                 v13 = v2->mv.baseclass_0.x;
//                 v12 = v2->mv.baseclass_0.y;
//                 v11 = v2->mv.baseclass_0.x;
//                 ArBoxCollision::ArBoxCollision(&thisa, v11, v12, v13, pObjecta);
//                 if ( !ExclusiveLogicLock<ArBoxCollision_XCriticalSection>::IsLocked(&ArcadiaServer::m_pData->rgnLock, v5, 0) )
//                     XSEH::InvokeUnhandledException(0xC000001Du);
//             }

            if (pObject.m_nArObjectType == 0)
            {
                Interlocked.Decrement(ref this.m_nItemCount);
                region.removeObject(pObject, region.m_vStaticObject);
            }
            if (pObject.m_nArObjectType == 1)
            {
                Interlocked.Decrement(ref this.m_nNPCCount);
                region.removeObject(pObject, region.m_vMOVABLEObject);
            }
            if (pObject.m_nArObjectType == 2)
            {
                Interlocked.Decrement(ref this.m_nUserCount);
                region.removeObject(pObject, region.m_vClientObject);
            }

            ArcadiaServerDeleteObjectArRegionFunctor fn = new ArcadiaServerDeleteObjectArRegionFunctor();
            fn.pObject = pObject;
            RappelzServer.m_Data.pRgnMgr.DoEachVisibleRegion(
                (uint)(pObject.mv.x / GameContent.g_nRegionSize),
                (uint)(pObject.mv.y / GameContent.g_nRegionSize),
                pObject.m_layer, fn);

        }
        
        //public void EnumMovableObject(int, int, int, int, unsigned char, class std::vector<unsigned int,std::allocator<unsigned int> > *, bool, bool)
        public void EnumMovableObject(ArPosition pos, byte layer, float range, List<uint> pvResult, bool bIncludeClient, bool bIncludeNPC)
        {
            EnumMovableObjectArRegionFunctor fn = new EnumMovableObjectArRegionFunctor(pvResult, pos, range, bIncludeClient, bIncludeNPC);
            RappelzServer.m_Data.pRgnMgr.DoEachVisibleRegion((uint)(pos.x / GameContent.g_nRegionSize),(uint)(pos.y / GameContent.g_nRegionSize), layer, fn);
        }

        // Function       :   public void ArcadiaServer::EnumMovableObjectInEveryRegion(int, int, int, int, unsigned char, class std::vector<unsigned int,std::allocator<unsigned int> > *, bool, bool)
        
        // Function       :   public void DoEachVisibleRegion(int, int, int, int, unsigned char, struct ArRegionFunctor &)
        public void DoEachVisibleRegion(int rx, int ry, byte layer, ArRegionFunctor fn)
        {
            RappelzServer.m_Data.pRgnMgr.DoEachVisibleRegion((uint)rx, (uint)ry, layer, fn);
        }
        // Function       :   public void ArcadiaServer::DoEachRegion(int, int, int, int, unsigned char, struct ArRegionFunctor &)
        // Function       :   public bool ArcadiaServer::SetMultipleMove(struct ArObject *, const struct ArPosition &, const class std::vector<ArPosition,std::allocator<ArPosition> > &, unsigned char, bool, unsigned long, bool)
        // Function       :   public bool ArcadiaServer::SetMove(struct ArObject *, const struct ArPosition &, const struct ArPosition &, unsigned char, bool, unsigned long, bool)
        // Function       :   public void ArcadiaServer::MoveObject(struct ArObject *, const struct ArPosition &, const float)
        // Function       :   public static struct ArcadiaIntf * GetIntf()
        // Function       :   public long GetLockedThreadCount()
        // Function       :   public long GetWaitingThreadCount()
        // Function       :   public const int & GetUserCount()
        // Function       :   public const int & GetNPCCount()
        // Function       :   public const int & GetItemCount()
        // Function       :   public static class ArcadiaServer & ArcadiaServer::Instance()
        // Function       :   private int ArcadiaServer::arcadia_lock(struct ArBoxCollision *, const char *, int)

        private void setObjectPriority(SchedulerObject obj, SchedulerObject.Priority priority)
        {
            if (RappelzServer.m_Data != null)
                RappelzServer.m_Data.scheduler.SetObjectPriority(obj, priority);
        }
        // Function       :   public void ArcadiaServer(const class ArcadiaServer &)
        // Function       :   private void ArcadiaServer::ArcadiaServer()
        
        private void step(BaseObject obj, uint tm)
        {
            ArPosition oldPos = new ArPosition();
            ArPosition newPos = new ArPosition();

            oldPos.x = obj.mv.x;
            oldPos.y = obj.mv.y;
            oldPos.z = obj.mv.z;
            oldPos.face = obj.mv.face;
            
            obj.Step(tm);

            newPos.x = obj.mv.x;
            newPos.y = obj.mv.y;
            newPos.z = obj.mv.z;
            newPos.face = obj.mv.face;
            this.onMoveObject(obj, oldPos, newPos);
            obj.lastStepTime = tm;

        }

        private void onMoveObject(BaseObject pObject, ArPosition oldPos, ArPosition newPos)
        {
            uint prev_rx = (uint)(oldPos.x / GameContent.g_nRegionSize);
            uint prev_ry = (uint)(oldPos.y / GameContent.g_nRegionSize);
            if (prev_rx != (uint)(newPos.x / GameContent.g_nRegionSize) || prev_ry != (uint)(newPos.y / GameContent.g_nRegionSize))
            {
                //                 if (GameRule.g_bUseRegionDebug )
                //                 {
                //                     ArBoxCollision::ArBoxCollision(&thisa, v4->x, v4->y, newPos->x, newPos->y);
                //                     if ( !ExclusiveLogicLock<ArBoxCollision_XCriticalSection>::IsLocked(&ArcadiaServer::m_pData->rgnLock, v6, 0) )
                //                         XSEH::InvokeUnhandledException(0xC000001Du);
                //                 }
                ArRegion r = RappelzServer.m_Data.pRgnMgr.GetRegion(prev_rx, prev_ry, pObject.m_layer);
                r.RemoveObject(pObject);
                r = RappelzServer.m_Data.pRgnMgr.GetRegion(pObject);
                r.AddObject(pObject);
            }
        }
       
        
        private void enterProc(BaseObject pObject, uint prx, uint pry)
        {
            SchedulerObject.Priority priority;

            float frs = (float)GameContent.g_nRegionSize;
            uint rx = (uint)(pObject.mv.x / frs);
            uint ry = (uint)(pObject.mv.y / frs);
            if (rx != prx || ry != pry )
            {
                ArcadiaServerenterProcArRegionFunctor fn = new ArcadiaServerenterProcArRegionFunctor();
                fn.bIsClientObject = pObject.m_nArObjectType == 2;
                fn.bIsSent = false;
                fn.obj = pObject;
                m_Data.pRgnMgr.DoEachNewRegion(rx, ry, prx, pry, pObject.m_layer, fn);
                if (fn.bIsSent )
                {
                    pObject.bIsNearClient = true;
                    if (pObject.m_nArObjectType == 1)
                    {
                        if (pObject.pending_priority == SchedulerObject.Priority.Null)
                            priority = pObject.priority;
                        else
                            priority = pObject.pending_priority;
                        if ((int)priority < 3)
                            this.SetObjectPriority(pObject, SchedulerObject.Priority.Normal);
                    }
                }
                if (pObject.m_nArObjectType == 2)
                {
                    m_Intf.SendRegionAckMessage(pObject, rx,ry);
                }
            }

        }

        public uint RunProcessPump()
        {
/*
            void *v1; // esi@1
            unsigned int v2; // ebx@7
            unsigned int v3; // ebx@9
            ArMoveVector::MOVE_INFO *v4; // eax@9
            ArMoveVector::MOVE_INFO *v5; // eax@10
            int v6; // ecx@10
            float v7; // eax@10
            unsigned int v8; // edx@10
            float v9; // ecx@10
            unsigned int *v10; // eax@13
            ArMoveVector::MOVE_INFO *v11; // eax@14
            float v12; // ebx@14
            int v13; // eax@14
            int v14; // ecx@14
            char *v18; // ebx@16
            int v19; // ecx@16
            int v26; // edx@21
            ArObject **v30; // eax@25
            char *v31; // ebx@26
            ArObject **v32; // eax@26
            unsigned int v33; // ebx@26
            ArObject **v34; // eax@26
            char *v35; // eax@29
            unsigned int v36; // eax@31
            std::_Vector_iterator<ArModifyTag,std::allocator<ArModifyTag> > result; // [sp+0h] [bp-84h]@36
            XScopedLock __scoped_lock; // [sp+8h] [bp-7Ch]@13
            unsigned int v43; // [sp+10h] [bp-74h]@9
            std::_Container_base *v44; // [sp+14h] [bp-70h]@13
            ArModifyTag *v45; // [sp+18h] [bp-6Ch]@13
            std::_Vector_iterator<ArModifyTag,std::allocator<ArModifyTag> > _First; // [sp+1Ch] [bp-68h]@36
            std::_Vector_iterator<ArModifyTag,std::allocator<ArModifyTag> > _Last; // [sp+24h] [bp-60h]@36
            std::_Vector_const_iterator<unsigned int,std::allocator<unsigned int> > this; // [sp+2Ch] [bp-58h]@4
            std::_Vector_const_iterator<ArObject *,std::allocator<ArObject *> > v49; // [sp+34h] [bp-50h]@35
            DWORD nLoopDelayCount; // [sp+3Ch] [bp-48h]@4
            std::_Vector_const_iterator<ArObject *,std::allocator<ArObject *> > _Right; // [sp+40h] [bp-44h]@12
            __int64 v52; // [sp+48h] [bp-3Ch]@9
            int v53; // [sp+50h] [bp-34h]@14
            volatile int *v54; // [sp+54h] [bp-30h]@16
            std::_Vector_iterator<ArModifyTag,std::allocator<ArModifyTag> > modify_it; // [sp+58h] [bp-2Ch]@1
            XScopedSpinLock __scoped_spinlock; // [sp+60h] [bp-24h]@14
            void *v57; // [sp+64h] [bp-20h]@25
            std::_Vector_iterator<ArSchedulerObject *,std::allocator<ArSchedulerObject *> > it; // [sp+68h] [bp-1Ch]@1
            char *pObj; // [sp+70h] [bp-14h]@14
            volatile int *nTmp32; // [sp+74h] [bp-10h]@15
            int v61; // [sp+80h] [bp-4h]@13
            char buf[1024]; // [sp+84h] [bp+0h]@1
            unsigned int v63; // [sp+484h] [bp+400h]@1
            void *pArga; // [sp+490h] [bp+40Ch]@1

            v63 = buf ^ __security_cookie;
            v1 = pArga;
            *&buf[1004] = *(pArga + 28);
            it.baseclass_0.baseclass_0.baseclass_0._Mycont = 0;
            it.baseclass_0._Myptr = 0;
            modify_it.baseclass_0.baseclass_0.baseclass_0._Mycont = 0;
            modify_it.baseclass_0._Myptr = 0;
            sprintf(buf, "Scheduler %02d");
            XThread::SetThreadName(-1, buf);
            if ( s_pfInitFunc )
            {
                *&buf[1004] = *(v1 + 28);
                s_pfInitFunc(*&buf[1004]);
            }
            *&buf[1004] = *(v1 + 28);
            sprintf(buf, "engine.scheduler.%d.debug");
            while ( !*(v1 + 104) )
            {
                ++*(v1 + 24);
                nLoopDelayCount = timeGetTime();
                std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                    &this,
                    *(v1 + 1),
                    v1);
                it.baseclass_0.baseclass_0.baseclass_0._Mycont = this.baseclass_0.baseclass_0._Mycont;
                it.baseclass_0._Myptr = this._Myptr;
                while ( 1 )
                {
                    std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                        &_Right,
                        *(v1 + 2),
                        v1);
                    if ( std::_Vector_const_iterator<X2D::Point<float>_std::allocator<X2D::Point<float>>>::operator__(
                             &it,
                             &_Right) )
                        break;
                    if ( *(v1 + 104) )
                        break;
                    if ( *(LODWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it)->end.x)
                         + 56) )
                    {
                        v2 = *(LODWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it)->end.x)
                             + 48);
                        std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                        std::vector<XLinearMemoryPool___std::allocator<XLinearMemoryPool__>>::operator__(v1, v2);
                        if ( *(LODWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it)->end.x)
                             + 24) != *(v1 + 24) )
                        {
                            if ( !*(LODWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it)->end.x)
                                  + 8) )
                            {
                                v43 = v7FFE000C;
                                v3 = v7FFE0008;
                                v52 = *(LODWORD(std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it)->end.x)
                                      + 16);
                                v4 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                                if ( (v52
                                    + __PAIR__(
                                          HIDWORD(AR_OBJECT_UPDATE_TIME[*(LODWORD(v4->end.x) + 40)]),
                                          LODWORD(AR_OBJECT_UPDATE_TIME[*(LODWORD(v4->end.x) + 40)]))) < __PAIR__(v43, v3) )
                                {
                                    v5 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it);
                                    v6 = *(v1 + 24);
                                    v7 = v5->end.x;
                                    v8 = v43;
                                    *(LODWORD(v7) + 16) = v3;
                                    *(LODWORD(v7) + 20) = v8;
                                    *(LODWORD(v7) + 24) = v6;
                                    v9 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&it)->end.x;
                                    *&buf[1004] = *(v1 + 28);
                                    (*(*LODWORD(v9) + 4))(*&buf[1004]);
                                }
                            }
                        }
                    }
                    std::_Vector_const_iterator<AutoAuctionInfo___std::allocator<AutoAuctionInfo__>>::operator__(&it);
                }
                (*(*(v1 + 8) + 4))(v1 + 32);
                *(v1 + 16) = "D:\\alienbrainWork\\Source Code\\@Rappelz\\Server\\GameServer_For_Update\\090721_GameServer\\Arcadia\\ArScheduler.cpp : ArSchedulerEngine";
                *(v1 + 17) = 401;
                __scoped_lock.m_lock = (v1 + 32);
                v10 = *(v1 + 5);
                v61 = 0;
                std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                    &v44,
                    v10,
                    v1 + 16);
                modify_it.baseclass_0.baseclass_0.baseclass_0._Mycont = v44;
                modify_it.baseclass_0._Myptr = v45;
                while ( 1 )
                {
                    std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                        &v49,
                        *(v1 + 6),
                        v1 + 16);
                    if ( std::_Vector_const_iterator<X2D::Point<float>_std::allocator<X2D::Point<float>>>::operator__(
                             &modify_it,
                             &v49) )
                        break;
                    v11 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&modify_it);
                    v12 = v11->end.x;
                    *&buf[1004] = LODWORD(v11->end.x) + 52;
                    pObj = LODWORD(v12);
                    XScopedSpinLock::XScopedSpinLock(&__scoped_spinlock, *&buf[1004]);
                    v13 = LODWORD(v12) + 32;
                    v14 = *(LODWORD(v12) + 32);
                    LOBYTE(v61) = 1;
                    v53 = LODWORD(v12) + 32;
                    if ( v14 == -1 )
                    {
                        nTmp32 = __scoped_spinlock.m_lock;
                        _EBX = __scoped_spinlock.m_lock;
                        _EAX = 0;
                        __asm { lock xchg eax, [ebx] }
                        goto LABEL_34;
                    }
                    v18 = pObj + 40;
                    v19 = *(pObj + 10);
                    v54 = (pObj + 40);
                    if ( v19 && *(pObj + 11) != *(v1 + 28) )
                    {
                        nTmp32 = __scoped_spinlock.m_lock;
                        _EBX = __scoped_spinlock.m_lock;
                        _EAX = 0;
                        __asm { lock xchg eax, [ebx] }
                        goto LABEL_34;
                    }
                    if ( *v13 != *(v1 + 28) )
                    {
                        nTmp32 = __scoped_spinlock.m_lock;
                        _EBX = __scoped_spinlock.m_lock;
                        _EAX = 0;
                        __asm { lock xchg eax, [ebx] }
                        goto LABEL_34;
                    }
                    v26 = *(pObj + 7);
                    nTmp32 = (pObj + 28);
                    if ( v26 == -1 )
                    {
                        nTmp32 = __scoped_spinlock.m_lock;
                        _EBX = __scoped_spinlock.m_lock;
                        _EAX = 0;
                        __asm { lock xchg eax, [ebx] }
                        goto LABEL_34;
                    }
                    if ( *(pObj + 7) )
                    {
                        *(pObj + 11) = *(v1 + 28);
                        if ( !*v18 )
                        {
                            std::vector<StructRoamer___std::allocator<StructRoamer__>>::push_back(v1, &pObj);
                            v36 = std::vector<KHash<RankingManager::_RANKING_DATA___khash_def::hashPr_mod_basic<int>>::node___std::allocator<KHash<RankingManager::_RANKING_DATA___khash_def::hashPr_mod_basic<int>>::node__>>::size(v1);
                            *(pObj + 12) = v36 - 1;
                            *v18 = *nTmp32;
                            ++*(v1 + 25);
        LABEL_32:
                            v13 = v53;
                            goto LABEL_33;
                        }
                    }
                    else
                    {
                        if ( *v18 )
                        {
                            v57 = std::_Vector_const_iterator<PartyManager::PartyInfo___std::allocator<PartyManager::PartyInfo__>>::operator_(&modify_it);
                            v30 = std::vector<_DUNGEON_RAID_INFO___std::allocator<_DUNGEON_RAID_INFO__>>::back(v1);
                            if ( *v57 != *v30 )
                            {
                                v31 = pObj + 48;
                                v57 = *(pObj + 12);
                                v32 = std::vector<_DUNGEON_RAID_INFO___std::allocator<_DUNGEON_RAID_INFO__>>::back(v1);
                                (*v32)->baseclass_0.priority_queue_index = v57;
                                v33 = *v31;
                                v57 = std::vector<_DUNGEON_RAID_INFO___std::allocator<_DUNGEON_RAID_INFO__>>::back(v1);
                                v34 = std::vector<XLinearMemoryPool___std::allocator<XLinearMemoryPool__>>::operator__(v1, v33);
                                v18 = v54;
                                *v34 = *v57;
                            }
                            if ( std::vector<KHash<RankingManager::_RANKING_DATA___khash_def::hashPr_mod_basic<int>>::node___std::allocator<KHash<RankingManager::_RANKING_DATA___khash_def::hashPr_mod_basic<int>>::node__>>::size(v1) )
                                *(v1 + 2) -= 4;
                            v35 = pObj;
                            *v18 = 0;
                            *(v35 + 11) = -1;
                            *(v35 + 12) = -1;
                            --*(v1 + 25);
                            goto LABEL_32;
                        }
                    }
        LABEL_33:
                    *nTmp32 = -1;
                    *v13 = -1;
                    v54 = __scoped_spinlock.m_lock;
                    _EBX = __scoped_spinlock.m_lock;
                    _EAX = 0;
                    __asm { lock xchg eax, [ebx] }
        LABEL_34:
                    std::_Vector_const_iterator<std::pair<GameContent::HUNTAHOLIC_MONSTER_RESPAWN_INFO_const___unsigned_long>_std::allocator<std::pair<GameContent::HUNTAHOLIC_MONSTER_RESPAWN_INFO_const___unsigned_long>>>::operator__(&modify_it.baseclass_0);
                }
                std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                    &_Last,
                    *(v1 + 6),
                    v1 + 16);
                std::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>::_Vector_const_iterator<StateDamage_std::allocator<StateDamage>>(
                    &_First,
                    *(v1 + 5),
                    v1 + 16);
                std::vector<X2D::Point<int>_std::allocator<X2D::Point<int>>>::erase(v1 + 1, &result, _First, _Last);
                v61 = -1;
                (*(*(v1 + 8) + 12))();
                nTmp32 = timeGetTime();
                if ( nLoopDelayCount + 100i64 > nTmp32 )
                {
                    *&buf[1004] = nLoopDelayCount - nTmp32 + 100;
                    Sleep(*&buf[1004]);
                }
            }
            *(v1 + 104) = 0;
            return 0;
*/

            return 0;
        }

        private int r_lock(BoxCollision pLockInfo)
        {
            return RappelzServer.m_Data.rgnLock.LockLogic(pLockInfo);
        }


        public RLock _Lock(uint rx, uint ry)
        {
            RLock rl = new RLock();
            BoxCollision box = new BoxCollision(rx,ry);
            rl.handle = r_lock(box);
            return rl;
        }

        public RLock _LockArea(uint rx1, uint ry1, uint rx2, uint ry2)
        {
            RLock rl = new RLock();
            BoxCollision box = new BoxCollision(rx1, ry1, rx2, ry2);
            rl.handle = r_lock(box);
            return rl;
        }

        public RLock _LockObject(BaseObject pObject)
        {
            RLock rl = new RLock();
            BoxCollision box = new BoxCollision((uint)(pObject.mv.x / GameContent.g_nRegionSize),(uint)(pObject.mv.y / GameContent.g_nRegionSize), -1);
            rl.handle = r_lock(box);
//             for ( i = ArcadiaServer::arcadia_lock(v15, v9, filename, linenumber);
//                   ;
//                   i = ArcadiaServer::arcadia_lock(v15, v11, filename, linenumber) )
//             {
//                 rl.handle = i;
//                 pObjecta = g_nRegionSize;
//                 if ( v8 == (v5->mv.baseclass_0.x / pObjecta) )
//                 {
//                     if ( ry == (v5->mv.baseclass_0.y / pObjecta) )
//                         break;
//                 }
//                 this.UnLock(rl);
//                 pObjectc = g_nRegionSize;
//                 v8 = (v5->mv.baseclass_0.x / pObjectc);
//                 ry = (v5->mv.baseclass_0.y / pObjectc);
//                 box = new BoxCollision((uint)(pObject.mv.x / GameContent.g_nRegionSize),(uint)(pObject.mv.y / GameContent.g_nRegionSize),0xFFFFFFFF);
//             }
            return rl;
        }

        public RLock _LockObjectWithSpecificRange(BaseObject pObject, uint range)
        {
            RLock rl = new RLock();
            BoxCollision box = new BoxCollision((uint)(pObject.mv.x / GameContent.g_nRegionSize),(uint)(pObject.mv.y / GameContent.g_nRegionSize), (int)range);
            rl.handle = r_lock(box);
//             for ( i = ArcadiaServer::arcadia_lock(v15, v9, filename, linenumber);
//                   ;
//                   i = ArcadiaServer::arcadia_lock(v15, v11, filename, linenumber) )
//             {
//                 rl.handle = i;
//                 pObjecta = g_nRegionSize;
//                 if ( v8 == (v5->mv.baseclass_0.x / pObjecta) )
//                 {
//                     if ( ry == (v5->mv.baseclass_0.y / pObjecta) )
//                         break;
//                 }
//                 this.UnLock(rl);
//                 pObjectc = g_nRegionSize;
//                 v8 = (v5->mv.baseclass_0.x / pObjectc);
//                 ry = (v5->mv.baseclass_0.y / pObjectc);
//                 box = new BoxCollision((uint)(pObject.mv.x / GameContent.g_nRegionSize),(uint)(pObject.mv.y / GameContent.g_nRegionSize),0xFFFFFFFF);
//             }
            return rl;
//             ArObject *v6; // esi@1
//             double v7; // st7@1
//             unsigned __int64 v8; // qax@1
//             unsigned int v9; // ebx@1
//             ArBoxCollision *v10; // eax@1
//             int i; // eax@1
//             ArBoxCollision *v12; // eax@4
//             ArBoxCollision thisa; // [sp+8h] [bp-1Ch]@1
//             unsigned int ry; // [sp+1Ch] [bp-8h]@1
//             ArcadiaServer *v16; // [sp+20h] [bp-4h]@1
//             float pObjectb; // [sp+30h] [bp+Ch]@1
//             float pObjecta; // [sp+30h] [bp+Ch]@2
//             float pObjectc; // [sp+30h] [bp+Ch]@4
// 
//             v6 = pObject;
//             pObjectb = g_nRegionSize;
//             v7 = v6->mv.baseclass_0.x;
//             v16 = this;
//             v8 = (v7 / pObjectb);
//             v9 = v8;
//             ry = (v6->mv.baseclass_0.y / pObjectb);
//             ArBoxCollision::ArBoxCollision(&thisa, v8, ry, range);
//             for ( i = ArcadiaServer::arcadia_lock(v16, v10, filename, linenumber);
//                   ;
//                   i = ArcadiaServer::arcadia_lock(v16, v12, filename, linenumber) )
//             {
//                 result->handle = i;
//                 pObjecta = g_nRegionSize;
//                 if ( v9 == (v6->mv.baseclass_0.x / pObjecta) )
//                 {
//                     if ( ry == (v6->mv.baseclass_0.y / pObjecta) )
//                         break;
//                 }
//                 ArcadiaServer::UnLock(v16, result);
//                 pObjectc = g_nRegionSize;
//                 v9 = (v6->mv.baseclass_0.x / pObjectc);
//                 ry = (v6->mv.baseclass_0.y / pObjectc);
//                 ArBoxCollision::ArBoxCollision(&thisa, v9, ry, range);
//             }
//             return result;
        }

        public RLock _LockObjectWithVisibleRange(BaseObject pObject)
        {
//             ArObject *v5; // esi@1
//             unsigned int v6; // ebx@1
//             unsigned int ry; // [sp+8h] [bp-8h]@1
//             ArcadiaServer *thisa; // [sp+Ch] [bp-4h]@1
//             float pObjectb; // [sp+1Ch] [bp+Ch]@1
//             float pObjecta; // [sp+1Ch] [bp+Ch]@2
//             float pObjectc; // [sp+1Ch] [bp+Ch]@4
// 
//             v5 = pObject;
//             pObjectb = g_nRegionSize;
//             thisa = this;
//             v6 = (v5->mv.baseclass_0.x / pObjectb);
//             ry = (v5->mv.baseclass_0.y / pObjectb);
            RLock rl = _Lock((uint)(pObject.mv.x / GameContent.g_nRegionSize),(uint)(pObject.mv.y / GameContent.g_nRegionSize));
            return rl;
//             while ( 1 )
//             {
//                 pObjecta = g_nRegionSize;
//                 if ( v6 == (v5->mv.baseclass_0.x / pObjecta) )
//                 {
//                     if ( ry == (v5->mv.baseclass_0.y / pObjecta) )
//                         break;
//                 }
//                 ArcadiaServer::UnLock(thisa, result);
//                 pObjectc = g_nRegionSize;
//                 v6 = (v5->mv.baseclass_0.x / pObjectc);
//                 ry = (v5->mv.baseclass_0.y / pObjectc);
//                 result->handle = ArcadiaServer::_Lock(
//                                      thisa,
//                                      &linenumber,
//                                      v6,
//                                      ry,
//                                      "D:\\alienbrainWork\\Source Code\\@Rappelz\\Server\\GameServer_For_Update\\090721_GameServer\\Arcadia\\ArcadiaServer.cpp",
//                                      494)->handle;
//             }
//             return result;
        }

        public RLock _LockWorld()
        {
            RLock rl = new RLock();
            BoxCollision pLockInfo = new BoxCollision(0,0,2147483647,2147483647);
            pLockInfo.bIsGlobal = true;
            rl.handle = this.r_lock(pLockInfo);
            return rl;
        }


        public void UnLock(RLock pLockHandle)
        {
            if (pLockHandle.handle >= 0)
                RappelzServer.m_Data.rgnLock.UnLock(pLockHandle.handle);
        }


        static public RappelzIntf m_Intf = new RappelzIntf();
        static public RappelzData m_Data = new RappelzData();

        public float m_nMapWidth;                   // 0x4
        public float m_nMapHeight;                  // 0x8
        public int m_nUserCount;                    // 0xC
        public int m_nNPCCount;                     // 0x10
        public int m_nItemCount;                    // 0x14
        // Function       :   public class ArcadiaServer & operator=(const class ArcadiaServer &)
        // Function       :   public void __local_vftable_ctor_closure()
        // Function       :   public void * __vecDelDtor(unsigned int)

    }
}
